//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using OpenLS.Core.Notification;

namespace OpenLS.Chart.UI
{
    abstract class ComplexCollection<T> : ViewModelBase, IList<T>, INotifyCollectionChanged
    {
        public virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
        {
            this.InvokeCollectionChanged(e);
            InvokePropertyChanged(new PropertyChangedEventArgs("Count"));

        }
        public void OnPropertyChanged(PropertyChangedEventArgs e)
        {
            InvokePropertyChanged(e);

        }

        protected readonly IList<T> _inner;
        private readonly WeakListener<INotifyCollectionChanged, NotifyCollectionChangedEventArgs> collectionWeakListener;
        private readonly WeakListener<INotifyPropertyChanged, PropertyChangedEventArgs> propertyWeakListener;

        protected ComplexCollection(IList<T> inner)
        {
            _inner = inner;

            if (inner is INotifyCollectionChanged)
            {
                var cc = (INotifyCollectionChanged) inner;
                collectionWeakListener = new WeakListener<INotifyCollectionChanged, NotifyCollectionChangedEventArgs>(unregister, this, GetType().GetMethod("OnCollectionChanged"));
                cc.CollectionChanged += collectionWeakListener.DoIt;
            }
            if (inner is INotifyPropertyChanged)
            {
                var cc2 = (INotifyPropertyChanged) inner;
                propertyWeakListener = new WeakListener<INotifyPropertyChanged, PropertyChangedEventArgs>(unregister, this, this.GetType().GetMethod("OnPropertyChanged"));
                cc2.PropertyChanged += propertyWeakListener.DoIt;
            }

        }
        public abstract IEnumerator<T> GetEnumerator();
        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        public abstract int Count { get; }

        public virtual bool IsReadOnly
        {
            get { throw new NotImplementedException(); }
        }

        public abstract T this[int index] { get; set; }

        public virtual void Add(T item)
        {
            throw new NotImplementedException();
        }

        public virtual void Clear()
        {
            throw new NotImplementedException();
        }

        public virtual int IndexOf(T item)
        {
            throw new NotImplementedException();
        }

        public virtual void Insert(int index, T item)
        {
            throw new NotImplementedException();
        }

        public virtual void RemoveAt(int index)
        {
            throw new NotImplementedException();
        }

        public virtual event NotifyCollectionChangedEventHandler CollectionChanged;
        public virtual event PropertyChangedEventHandler PropertyChanged;

        public virtual bool Contains(T item)
        {
            throw new NotImplementedException();
        }

        public virtual void CopyTo(T[] array, int arrayIndex)
        {
            throw new NotImplementedException();
        }

        public virtual bool Remove(T item)
        {
            throw new NotImplementedException();
        }

        private void unregister(object obj)
        {
            INotifyCollectionChanged cc = (INotifyCollectionChanged)_inner;
            cc.CollectionChanged -= collectionWeakListener.DoIt;
        }

        protected void InvokeCollectionChanged(NotifyCollectionChangedEventArgs e)
        {
            NotifyCollectionChangedEventHandler changed = CollectionChanged;
            if (changed != null) changed(this, e);
        }

        protected void InvokePropertyChanged(PropertyChangedEventArgs e)
        {
            PropertyChangedEventHandler changed = PropertyChanged;
            if (changed != null) changed(this, e);
        }
    }
}